package com.xuanwei.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuanwei.core.cache.UserCache;
import com.xuanwei.core.exception.XwException;
import com.xuanwei.core.service.IXwManagementRoleService;
import com.xuanwei.core.service.IXwManagementService;
import com.xuanwei.core.util.JwtTokenUtil;
import com.xuanwei.dao.entity.XwManagement;
import com.xuanwei.dao.entity.XwManagementRole;
import com.xuanwei.dao.mapper.XwManagementMapper;
import com.xuanwei.xwcommon.consts.CacheName;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * @Author jiangyong
 * @Description TODO
 * @Date 2019/4/17 17:02
 **/
@Service
public class XwManagementServiceImpl extends ServiceImpl<XwManagementMapper, XwManagement> implements IXwManagementService {

    @Autowired
    private JwtTokenUtil tokenUtil;

    @Autowired
    private IXwManagementRoleService managementRole;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private UserCache userCache;

    @Override
    public String login(String username, String password) {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
        Authentication authentication = authenticationManager.authenticate(authenticationToken);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        String token = tokenUtil.generateToken(userDetails);
        redisTemplate.opsForValue().set(CacheName.MANAGER_TOKEN +username, token, 7, TimeUnit.DAYS);
        return token;
    }

    @Override
    public void logout() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String name = authentication.getName();
        redisTemplate.delete(CacheName.MANAGER_TOKEN +name);
        userCache.delete(name);
    }

    @Override
    public XwManagement findByUsername(String username) {
        QueryWrapper<XwManagement> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        return getBaseMapper().selectOne(wrapper);
    }

    @Override
    public XwManagementRole findByUserId(Integer id) {

        return managementRole.findPermissionByUserId(id);
    }

    @Override
    public void addOrUpdate(XwManagement management) {
        management.setPassword(DigestUtils.md5DigestAsHex(management.getPassword().getBytes()));
        management.setUpdateTime(LocalDateTime.now());
        if (management.getId() == null) {
            XwManagement xwManagement = findByUsername(management.getUsername());
            if(xwManagement!=null){
                throw new XwException("该账户已存在");
            }
            management.setCreateTime(LocalDateTime.now());
            getBaseMapper().insert(management);
        } else {
            XwManagement management1 = getBaseMapper().selectById(management.getId());
            if (management1 == null) {
                throw new XwException("不存在该数据");
            }
            userCache.delete(management.getUsername());
            redisTemplate.delete(CacheName.MANAGER_TOKEN +management.getUsername());
            getBaseMapper().updateById(management);
        }

    }

    @Override
    public void delete(Integer id) {
        XwManagement management = getBaseMapper().selectById(id);
        String username = management.getUsername();
        String name = SecurityContextHolder.getContext().getAuthentication().getName();
        if (name != null && name.equals(username)) {
            throw new XwException("不能删除自己");
        }
        userCache.delete(username);
        redisTemplate.delete(CacheName.MANAGER_TOKEN +username);
        getBaseMapper().deleteById(id);
    }

    @Override
    public void list(Page<XwManagement> page) {
        getBaseMapper().selectPage(page,
                new QueryWrapper<XwManagement>()
                        .select("id,nickname,role_name,role_id,username,create_time"));


    }
}
